package com.usian.comment.service.impl;

import com.usian.comment.controller.v1.CommentReplyVo;
import com.usian.comment.entity.ApComment;
import com.usian.comment.entity.ApCommentReply;
import com.usian.comment.entity.ApCommentReplyLike;
import com.usian.comment.service.CommentReplyService;
import com.usian.common.enums.AppHttpCodeEnum;
import com.usian.common.exception.LeadException;
import com.usian.common.threadlocal.UserThreadLocalUtils;
import com.usian.common.util.BeanHelper;
import com.usian.model.comment.dtos.CommentReplyDto;
import com.usian.model.comment.dtos.CommentReplyLikeDto;
import com.usian.model.comment.dtos.CommentReplySaveDto;
import com.usian.model.user.dtos.UserInfoDto;
import com.usian.user.client.UserFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class CommentReplyServiceImpl implements CommentReplyService {

    @Autowired
    private UserFeign userFeign;

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 保存评论回复
     */
    @Override
    public void saveCommentReply(CommentReplySaveDto dto) {
//        参数校验
        if (dto==null){
            throw new LeadException(AppHttpCodeEnum.PARAM_REQUIRE);
        }
//        获取用户id,先登录，再操作
        Integer userId = UserThreadLocalUtils.getUserId();
        if (userId==null || userId==0){
            throw new LeadException(AppHttpCodeEnum.NEED_LOGIN);
        }
//        获取用户信息
        UserInfoDto userInfoDto = userFeign.findById(userId);
//        构造回复对象
        ApCommentReply apCommentReply = new ApCommentReply();
        apCommentReply.setAuthorId(userId);
        apCommentReply.setAuthorName(userInfoDto.getName());
        apCommentReply.setCommentId(dto.getCommentId());
        apCommentReply.setContent(dto.getContent());
        apCommentReply.setLikes(0);
        apCommentReply.setCreatedTime(new Date());
        apCommentReply.setUpdatedTime(new Date());
        mongoTemplate.insert(apCommentReply);
//        更新评论的回复数量
        Query query = new Query().addCriteria(Criteria.where("_id").is(dto.getCommentId()));
        Update update = new Update();
        update.inc("reply",1);
        mongoTemplate.updateFirst(query,update, ApComment.class);
    }

    /**
     * 查询回复列表
     */
    @Override
    public List<CommentReplyVo> loadCommentReply(CommentReplyDto dto) {
//        参数校验
        if (dto.getSize()==null || dto.getSize()==0){
            dto.setSize(20L);
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("commentId").is(dto.getCommentId()));
        if (dto.getMinLikes()!=null && dto.getMinLikes()>0){
            query.addCriteria(Criteria.where("likes").lt(dto.getMinLikes()));
        }
        query.with(Sort.by(Sort.Direction.DESC,"likes"))
                       .limit(dto.getSize().intValue());
        List<ApCommentReply> apCommentReplies = mongoTemplate.find(query, ApCommentReply.class);
        if (CollectionUtils.isEmpty(apCommentReplies)){
            return null;
        }
        List<CommentReplyVo> commentReplyVos = BeanHelper.copyWithCollection(apCommentReplies, CommentReplyVo.class);
//        获取用户id
        Integer userId = UserThreadLocalUtils.getUserId();
        if (userId==null || userId==0){
            return commentReplyVos;
        }
//        获取回复id集合
        List<String> replyIds = commentReplyVos.stream().map(CommentReplyVo::getId).collect(Collectors.toList());
        query = new Query().addCriteria(Criteria.where("commentReplyId")
                                                .in(replyIds)
                                                .and("authorId")
                                                .is(userId)
                                                .and("operation")
                                                .is(0));
        List<ApCommentReplyLike> apCommentReplyLikes = mongoTemplate.find(query, ApCommentReplyLike.class);
        if (!CollectionUtils.isEmpty(apCommentReplies)){
            List<String> likeReplyIds = apCommentReplyLikes.stream().map(ApCommentReplyLike::getCommentReplyId).collect(Collectors.toList());
            commentReplyVos.stream().forEach(commentReplyVo -> {
                if(likeReplyIds.contains(commentReplyVo.getId())){
                    commentReplyVo.setOperation(0);
                }
            });
        }
        return commentReplyVos;
    }

    /**
     * 回复点赞
     */
    @Override
    public Map<String, Object> saveCommentReplyLike(CommentReplyLikeDto dto) {
//        参数校验
        if (dto==null){
            throw new LeadException(AppHttpCodeEnum.PARAM_REQUIRE);
        }
//        获取用户id
        Integer userId = UserThreadLocalUtils.getUserId();
        if (userId==null){
            throw new LeadException(AppHttpCodeEnum.NEED_LOGIN);
        }
        ApCommentReply apCommentReply = mongoTemplate.findById(dto.getCommentRepayId(), ApCommentReply.class);
//        返回数据
        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put("likes",apCommentReply.getLikes());
//        查询点赞信息
        Query query = Query.query(Criteria.where("commentReplyId")
                                          .is(dto.getCommentRepayId())
                                          .and("authorId")
                                          .is(userId));
        ApCommentReplyLike apCommentReplyLike = mongoTemplate.findOne(query, ApCommentReplyLike.class);
        if (apCommentReplyLike==null && dto.getOperation()==0){
            //更新评论回复点赞数量
            Query query2 = Query.query(Criteria.where("_id").is(dto.getCommentRepayId()));
            Update update = new Update();
            update.inc("likes");
            mongoTemplate.updateFirst(query2,update,ApCommentReply.class);

            //保存app评论回复点赞
            apCommentReplyLike = new ApCommentReplyLike();
            apCommentReplyLike.setAuthorId(userId);
            apCommentReplyLike.setCommentReplyId(dto.getCommentRepayId());
            apCommentReplyLike.setOperation(dto.getOperation());
            mongoTemplate.save(apCommentReplyLike);
        }else if (apCommentReplyLike!=null &&
                  apCommentReplyLike.getOperation().intValue()!=dto.getOperation().intValue()){
            //更新评论回复点赞状态
            apCommentReplyLike.setOperation(dto.getOperation());
            mongoTemplate.save(apCommentReplyLike);
            int opt = dto.getOperation()==0?1:-1;
            if (opt==-1 && apCommentReply.getLikes()<1){
                apCommentReply = mongoTemplate.findById(dto.getCommentRepayId(), ApCommentReply.class);
                resultMap.put("likes",apCommentReply);
                return resultMap;
            }
            //更新评论的点赞数量
            Query query3 = Query.query(Criteria.where("_id").is(dto.getCommentRepayId()));
            Update update = new Update();
            update.inc("likes",opt);
            mongoTemplate.updateFirst(query3,update,ApCommentReply.class);
        }
//        数据返回
        apCommentReply = mongoTemplate.findById(dto.getCommentRepayId(),ApCommentReply.class);
        resultMap.put("likes",apCommentReply.getLikes());
        return resultMap;
    }
}
